# -*- coding: UTF-8 -*-
# @description : python
# @Author : zyl
# @Time : 2021/9/6 16:00
# @Remark: 视频监控组DB
import logging

from mxsoftpy import DB
from mxsoftpy.TreeDB import symbol_map
from mxsoftpy.db_def.def_type import type_map
from mxsoftpy.db_def.def_tree import TDDB_OPKF_CREATEDYNKEY, TRDB_OPKF_OPENEXIST
from mxsoftpy.exception import ParamsError, DBError
from utils.conf.mxconfig import MxConfig


class GroupDB(DB):

    def check_label(self, data):
        """
        检查IP和名称是否重复
        :param data:
        :return:
        """
        QIS = list()
        if data['GroupName']:
            QIS.append({"name": "GroupName", "nCondition": symbol_map['e'], "vLiData": data['GroupName'],
                        "vLiDataType": type_map['str']})

        self.tree.open('VideoMonitor', 'Group', file='IOT', host=MxConfig.HOST, port=MxConfig.PORT)
        key = list()
        self.tree.exec_bs('bs_treedb_query_subkey_by_condition', QIS, '', key, 0, 0)
        if 'id' in data:
            if data['id'] not in key:
                if key:
                    raise Exception('名称已存在')
        else:
            if key:
                raise Exception('名称已存在')

    def create(self, **kwargs) -> int:
        """
        添加视频监控组信息
        :param kwargs: 添加数据 字典
        :return: 返回添加主键ID 字符串
        """
        try:
            self.tree.open('VideoMonitor', 'Group', file='IOT', host=MxConfig.HOST, port=MxConfig.PORT)
            # self.tree.exec_tree('Treedb_BeginTransaction')
            self.check_label(kwargs)
            # self.tree.begin()
            # groupid = self.tree.exec_tree('Treedb_InsertSubKey', '', TDDB_OPKF_CREATEDYNKEY)
            # self.tree.exec_tree('Treedb_ReopenSubKey', 'Group\\' + groupid, TRDB_OPKF_OPENEXIST)
            # self.tree.insert_items([(k, v) for k, v in kwargs.items()])
            # self.tree.exec_tree('Treedb_CommitTransaction')

            sres = self.tree.insert_key_items([(k, v) for k, v in kwargs.items()])
            # self.tree.commit()
            # self.tree.exec_tree('Treedb_CommitTransaction')
            return sres
        except Exception as e:
            # self.tree.exec_tree('Treedb_RollbackTransaction')
            self.tree.rollback()
            raise e

    def group_dict(self, **kwargs) -> dict:
        """
        返回所有视频组数据
        :param kwargs:  查询参数 字典
        :return:  返回组数据 字典
        """
        self.tree.open('VideoMonitor', 'Group', file='IOT', host=MxConfig.HOST, port=MxConfig.PORT)
        key = []
        if 'GroupName' in kwargs:
            GroupName = kwargs['GroupName']
            QIS = [{"name": "GroupName", "nCondition": symbol_map['nclike'], "vLiData": '*' + GroupName + '*',
                    "vLiDataType": type_map['str']}]

            self.tree.exec_bs('bs_treedb_query_subkey_by_condition', QIS, '', key, 0, 0)

        result = dict()
        self.tree.exec_bs('bs_treedb_get_subkey_properties', key, [], result)
        return result

    def group_dict_name(self) -> dict:
        """
        返回所有视频组数据按照名称
        :return:  返回组数据 字典
        """
        self.tree.open('VideoMonitor', 'Group', file='IOT', host=MxConfig.HOST, port=MxConfig.PORT)
        result = dict()
        self.tree.exec_bs('bs_treedb_get_subkey_properties', [], ['GroupName'], result)
        tmp = dict()
        for key, val in result.items():
            tmp[val['GroupName']] = key
        return tmp

    def loopData(self, data, groupid, result):
        """
        递归获取数据
        :param data: 数据字典
        :param groupid: 组ID
        :param result: 返回数据字典
        :return:
        """
        for key, val in data.items():
            if val['parent'] == groupid:
                result.append(key)
                self.loopData(data, key, result)

    def GetGroup(self, groupid):
        """
        获取分组下级
        :param groupid: 组ID
        :return:
        """
        data = []
        result = {}
        self.tree.exec_bs('bs_treedb_get_subkey_properties', [], [], result)
        self.loopData(result, groupid, data)
        data.append(groupid)
        return data

    def check_del(self, groups_list) -> None:
        """
        检查视频监控组是否添加监控信息
        :param sdelid: 组ID
        :return:
        """
        QIS = list()
        conditions = ''
        for key, id in enumerate(groups_list):
            QIS.append({"name": "GroupId", "nCondition": symbol_map['e'], "vLiData": int(id),
                        "vLiDataType": type_map['int']})
            conditions += str(key) + ' or '
        conditions = conditions[:-3]
        self.tree.open('VideoMonitor', 'Config', file='IOT', host=MxConfig.HOST, port=MxConfig.PORT)
        key = []
        self.tree.exec_bs('bs_treedb_query_subkey_by_condition', QIS, conditions, key, 0, 0)
        if len(key) > 0:
            raise Exception('该分组下存在监控，请删除或移动监控后重试')

    def delete(self, sdelid) -> int:
        """
        删除组
        :param delid: 组ID
        :return: 删除得组ID  字符串
        """
        if sdelid:  # 只有列表中有值才执行操作，防止删除整个视频组
            self.tree.open('VideoMonitor', 'Group', file='IOT',
                           host=MxConfig.HOST, port=MxConfig.PORT)
            groupids = self.GetGroup(sdelid)
            self.check_del(groupids)
            try:
                for sid in groupids:
                    self.tree.open('VideoMonitor', 'Group\\' + sid, file='IOT',
                                   host=MxConfig.HOST, port=MxConfig.PORT).delete()
            except Exception as e:
                logging.error('删除组失败, %s' % str(e))
        return sdelid

    def update(self, sgroupId, **kwargs) -> str:
        """
        更新视频组名称
        :param sgroupId: 视频组ID
        :param kwargs: 字典  前台参数
        :return: 修改得组名称 字符串
        """
        try:
            self.check_label(kwargs)
            self.tree.open('VideoMonitor', 'Group\\' + sgroupId, file='IOT',
                           host=MxConfig.HOST, port=MxConfig.PORT).insert_item('GroupName', kwargs['GroupName'])
        except DBError as e:
            raise ParamsError('更新数据失败, %s' % str(e))
        return kwargs['GroupName']
